////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "WNMemory/inc/WNMemory.h"
#include "WNMath/inc/WNSegment2.h"
#include "WNMath/inc/WNExtended.h"
#include "WNMath/inc/WNLine2.h"
#include "WNMath/inc/WNLine3.h"
#include "WNMath/inc/WNRay2.h"
#include "WNMath/inc/WNRay3.h"
#include "WNMath/inc/WNVector2.h"

using namespace WNMath;
using namespace WNMemory;

// Constructors ////////////////////////////////////////////////////////////////////////////////////

WNSegment2::WNSegment2() :
    start(0.0f, 0.0f),
    end(0.0f, 0.0f) {
}

WNSegment2::WNSegment2(const WN_FLOAT32* _f) :
    start(_f[0], _f[1]),
    end(_f[2], _f[3]) {
}

WNSegment2::WNSegment2(const WNPoint2& _point1, const WNPoint2& _point2) :
    start(_point1),
    end(_point2) {
}

// Operators ///////////////////////////////////////////////////////////////////////////////////////

WNSegment2 WNSegment2::operator + () const {
    return(*this);
}

WNSegment2 WNSegment2::operator - () const {
    return(WNSegment2(-start, -end));
}

WN_BOOL WNSegment2::operator == (const WNSegment2& _seg) const {
    return(0 == WNMemCmp(this, &_seg, sizeof(WNSegment2)));
}

WN_BOOL WNSegment2::operator != (const WNSegment2& _seg) const {
    return(0 != WNMemCmp(this, &_seg, sizeof(WNSegment2)));
}

// Members /////////////////////////////////////////////////////////////////////////////////////////

WN_VOID WNSegment2::Zero() {
    start.Zero();
    end.Zero();
}

WN_VOID WNSegment2::Set(const WN_FLOAT32* _f) {
    start.x = _f[0];
    start.y = _f[1];

    end.x = _f[2];
    end.y = _f[3];
}

WN_VOID WNSegment2::Set(const WNPoint2& _point1, const WNPoint2& _point2) {
    start = _point1;
    end = _point2;
}

WN_FLOAT32 WNSegment2::Length() const {
    return(WNDistance(start, end));
}

WN_FLOAT32 WNSegment2::LengthSquared() const {
    return(WNDistanceSquared(start, end));
}

WNVector2 WNSegment2::Direction() const {
    return(end - start);
}

WNLine2 WNSegment2::ToLine2() const {
    return(WNLine2(start, end));
}

WNLine3 WNSegment2::ToLine3() const {
    return(WNLine3(start.ToPoint3(), end.ToPoint3()));
}

WNRay2 WNSegment2::ToRay2() const {
    return(WNRay2(start, end - start));
}

WNRay3 WNSegment2::ToRay3() const {
    return(WNRay3(start.ToPoint3(), (end - start).ToVector3()));
}